// Copyright 2009 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Author: Gunnar Ritter
//
// A command line frontend for the POP/IMAP troubleshooter, mainly for
// development and for use within scripts.

#ifndef POPDIAG_CMDLINE_CMDLINE_H_
#define POPDIAG_CMDLINE_CMDLINE_H_

#include <stdio.h>
#include <QCoreApplication>
#include <QStringList>

#include "probes/executive.h"

namespace popdiag_cmdline {

// Exit status codes for the command line program, following
// standard Unix conventions.
enum {
  EXIT_CODE_SUCCESS         = 0,
  EXIT_CODE_RUNTIME_FAILURE = 1,
  EXIT_CODE_SYNTAX_ERROR    = 2
};

// This class executes a probe based on the command line arguments
// given to the constructor. It needs to be called from a context
// that provides a QCoreApplication object.
class Cmdline : public QObject {
  Q_OBJECT
 public:
  // Note that the argv array may be permuted by an internal call
  // to the getopt_long() function within this class.
  Cmdline(int argc, char **argv);
  ~Cmdline();

  // Starts parsing the command line options, doing the actions
  // advised in them, e.g. opening output files, and executing the
  // probes. Returns a non-zero value for an error during initialization,
  // such as an invalid argument, or zero otherwise. After a zero return,
  // the surrounding QCoreApplication object needs to execute the exec()
  // method to complete the execution of the probes.
  int Start();

  // Redirects standard error to the given file name. This is
  // mainly useful for testing.
  void SetErrorFile(QString name);

 public slots:
  // A callback for the Executive class that is invoked when
  // there is updated progress information. It prints the progress
  // to standard error, unless the -q option was given. The output
  // consists of a decimal percentage, overwriting the previous
  // percentage on the same row of the terminal. The current
  // percentage value is computed as (progress_made / estimated_total)
  // internally.
  void OnProgressMade(int progress_made, int estimated_total);

  // Writes the report to standard output or to the file
  // given with the -o option.
  void OnReportReady();

  // Exits the command line program once the Executive object
  // is finished.
  void OnExecutiveDone();

 private:
  // Prints an error message, using the given program name.
  void Error(QString progname, QString error);

  // Prints an error message, followed by the usage message.
  void Usage(QString progname, QString error);

  popdiag::Executive *executive_;
  bool quiet_;
  // Where to write the HTML report to.
  FILE *output_;
  // Where to print progress and error messages.
  FILE *stderr_;
  int argc_;
  char **argv_;
  DISALLOW_EVIL_CONSTRUCTORS(Cmdline);
};

// A wrapper around the getopt_long() C function that takes
// the command line option, parses it, and makes the option
// values accessible as methods.
class CmdlineOptions : public QObject {
  Q_OBJECT
 public:
  CmdlineOptions();

  // Parses the command line. This needs to be done before
  // any of the accessor methods can return anything but
  // the default values.
  bool Getopt(int argc, char **argv);

  const QString progname() const { return progname_; }
  const QString error() const { return error_; }
  const QString username() const { return username_; }
  const QString password() const { return password_; }
  const QString imap_server() const { return imap_server_; }
  const QString pop_server() const { return pop_server_; }
  const QString smtp_server() const { return smtp_server_; }
  int smtp_port() const { return smtp_port_; }
  const QString output() const { return output_; }
  bool pull_all_mail() const { return pull_all_mail_; }
  bool quiet() const { return quiet_; }
  bool debug() const { return debug_; }

 private:
  QString progname_;
  QString error_;
  QString username_;
  QString password_;
  QString imap_server_;
  QString pop_server_;
  QString smtp_server_;
  int smtp_port_;
  QString output_;
  bool pull_all_mail_;
  bool quiet_;
  bool debug_;
  DISALLOW_EVIL_CONSTRUCTORS(CmdlineOptions);
};

}  // namespace popdiag_cmdline

#endif  // POPDIAG_CMDLINE_CMDLINE_H_
